package com.github.monkeywie.proxyee.intercept.common;

import com.github.monkeywie.proxyee.intercept.HttpProxyIntercept;
import com.github.monkeywie.proxyee.intercept.HttpProxyInterceptPipeline;
import com.github.monkeywie.proxyee.intercept.HttpTunnelIntercept;
import com.github.monkeywie.proxyee.log.LogRecorder;
import com.github.monkeywie.proxyee.log.LogRecorderFactory;
import com.github.monkeywie.proxyee.util.ProtoUtil;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;

import java.nio.charset.Charset;

public class LogIntercept extends HttpProxyIntercept implements HttpTunnelIntercept {
    private final static LogRecorder logRecorder= LogRecorderFactory.getRecorder(LogIntercept.class);
    private final static String lineSeparator=System.getProperty("line.separator");
    private boolean detailed=false;

    public LogIntercept(){
    }
    public LogIntercept(boolean detailed){
        this.detailed=detailed;
    }

    public void beforeRequest(Channel clientChannel, HttpRequest httpRequest, HttpProxyInterceptPipeline pipeline) throws Exception {
        StringBuilder sb=new StringBuilder();
        httpRequest.headers().forEach(header->{
            sb.append(header.getKey()).append(":").append(header.getValue()).append(lineSeparator);
        });
        logRecorder.info("{} {} {} {}{}",httpRequest.method(),httpRequest.uri(),httpRequest.protocolVersion(),lineSeparator,sb.toString());
        super.beforeRequest(clientChannel,httpRequest,pipeline);
    }


    public void beforeRequest(Channel clientChannel, HttpContent httpContent, HttpProxyInterceptPipeline pipeline) throws Exception {
        if(detailed){
            logRecorder.info("{}",httpContent.content().toString(Charset.defaultCharset()));
        }
        super.beforeRequest(clientChannel,httpContent,pipeline);
    }


    public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpResponse httpResponse, HttpProxyInterceptPipeline pipeline) throws Exception {
        StringBuilder sb=new StringBuilder();
        httpResponse.headers().forEach(header->{
            sb.append(header.getKey()).append(":").append(header.getValue()).append(lineSeparator);
        });
        logRecorder.info("{} {} {}{}",httpResponse.protocolVersion(),httpResponse.status(),lineSeparator,sb.toString());
        super.afterResponse(clientChannel,proxyChannel,httpResponse,pipeline);
    }


    public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpContent httpContent, HttpProxyInterceptPipeline pipeline) throws Exception {
        if(detailed){
            logRecorder.info("{}",httpContent.content().toString(Charset.defaultCharset()));
        }
        super.afterResponse(clientChannel,proxyChannel,httpContent,pipeline);
    }

    @Override
    public void handle(ProtoUtil.RequestProto requestProto) {
        logRecorder.info("tunnel host={},port={},isSsl={}",requestProto.getHost(),requestProto.getPort(),requestProto.getSsl());
    }
}
